import axios from 'axios'
import store from '@/store'
import storage from 'store'
import notification from 'ant-design-vue/es/notification'
import { VueAxios } from './axios'
import { ACCESS_TOKEN, REFRESH_TOKEN } from '@/store/mutation-types'
// import { ACCESS_TOKEN } from '@/store/mutation-types'
import { login } from '@/api/login'
import qs from 'qs'

// 创建 axios 实例
const request = axios.create({
  // API 请求的默认前缀
  baseURL: process.env.VUE_APP_API_BASE_URL,
  timeout: 60000 // 请求超时时间
})
let showMsg = true
// 是否正在刷新
let isRefreshing = false
// 数据报错请求队列
let requests = []

// 异常拦截处理器
const errorHandler = (error) => {
  if (error.response) {
    if (error.response.status === 401) {
      if (showMsg) {
        showMsg = false
        notification.error({
          message: '账号已离线',
          description: '您的账号已离线，请重新登录'
        })
        setTimeout(() => {
          storage.remove(ACCESS_TOKEN)
          storage.remove(REFRESH_TOKEN)
          window.location.href = '/login'
          showMsg = true
        }, 5000)
      }
      return
    }
  }
  return Promise.reject(error)
}

// request interceptor
request.interceptors.request.use(config => {
  const token = storage.get(ACCESS_TOKEN)
  // 如果 token 存在
  // 让每个请求携带自定义 token 请根据实际情况自行修改
  if (token) {
    config.headers['Authorization'] = token
  }
  if (config['setJson']) {
    config.headers['Content-Type'] = 'application/json'
  }
  return config
}, errorHandler)

// response interceptor
request.interceptors.response.use((response) => {
  // fix: 2022-09-14
  // 如果响应code码等于209 视为当前toke过期，重新调用登录接口刷新token
  if (response.status === 200 && response.data.code === 209) {
    const config = response.config
    if (!isRefreshing) {
      isRefreshing = true
      storage.remove(ACCESS_TOKEN)
      return login(qs.stringify({
        grant_type: 'refresh_token',
        refresh_token: storage.get(REFRESH_TOKEN)
      })).then(res => {
        const successToken = res.token_type + ' ' + res.access_token
        const refreshToken = res.refresh_token
        store.set('ACCESS_TOKEN', successToken)
        store.set('REFRESH_TOKEN', refreshToken)
        requests.forEach(cb => cb(successToken))
        requests = []
        return request(config)
      }).catch(() => {
        storage.remove(ACCESS_TOKEN)
        storage.remove(REFRESH_TOKEN)
        window.location.href = '/login'
      }).finally(() => {
        isRefreshing = false
      })
    } else {
      // 正在刷新token，返回一个未执行resolve的promise
      return new Promise((resolve) => {
        requests.push((token) => {
          config.headers['Authorization'] = token
          resolve(request(config))
        })
      })
    }
  } else {
    return response.data
  }
  // return response.data
}, errorHandler)

const installer = {
  vm: {},
  install (Vue) {
    Vue.use(VueAxios, request)
  }
}

export default request

export {
  installer as VueAxios,
  request as axios
}
